using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using dotnetCHARTING.WinForms;
using System.Collections;

namespace Budgetor.DataVizualization
{
    public partial class BarGraphPanel : UserControl, IDataVizualizationPanel
    {
        Dictionary<string, bool> descriptionList = new Dictionary<string, bool>();
        Dictionary<string, bool> categoryList = new Dictionary<string, bool>();

        Dictionary<string, Dictionary<string, bool>> filterList = new Dictionary<string, Dictionary<string, bool>>();

        public BarGraphPanel()
        {
            InitializeComponent();
            comboBoxDisplay.SelectedIndex = 0;
            comboBoxCategorize.SelectedIndex = 0;

            foreach (object obj in comboBoxCategorize.Items)
            {
                filterList.Add(obj.ToString(), new Dictionary<string, bool>());
            }

            InitChart();
        }

        private static Color[] colorList = new Color[] { 
                Color.Red, Color.Blue, Color.Green, Color.Cyan, Color.Magenta,
                Color.Yellow, Color.Gray, Color.Maroon, Color.Brown, Color.Tomato,
                Color.Sienna, Color.Orange, Color.Olive, Color.Lime, Color.SeaGreen,
                Color.DarkSlateGray, Color.RoyalBlue, Color.Indigo, Color.Violet, Color.Purple};

        private void InitChart()
        {
            barChart.DateGrouping = TimeInterval.Days;
            barChart.Palette = colorList;
            barChart.YAxis.Scale = dotnetCHARTING.WinForms.Scale.Stacked;
        }

        #region IDataVizualizationPanel Members

        Data[] dataCollection;

        public void UpdateData(object sender, DataEventArgs e)
        {
            this.dataCollection = e.DataCollection;

            if (e.DataCollection.Length == 0)
                return;

            dateTimePickerFrom.Value = e.DataCollection[0].Date;
            dateTimePickerTo.Value = e.DataCollection[e.DataCollection.Length - 1].Date;

            checkedListBoxIncludeData.Items.Clear();

            foreach (Data dataItem in this.dataCollection)
            {
                if (!descriptionList.ContainsKey(dataItem.Description))
                    descriptionList.Add(dataItem.Description, true);

                if (!categoryList.ContainsKey(dataItem.Category))
                    categoryList.Add(dataItem.Category, true);
            }

            PopulateList();

            UpdateChart();
        }

        private void PopulateList()
        {
            checkedListBoxIncludeData.ItemCheck -= OnItemCheck;

            checkedListBoxIncludeData.Items.Clear();

            if (comboBoxCategorize.SelectedIndex == 1)
            {
                foreach (string text in categoryList.Keys)
                {
                    checkedListBoxIncludeData.Items.Add(text, categoryList[text]);
                }
            }
            else
            {
                foreach (string text in descriptionList.Keys)
                {
                    checkedListBoxIncludeData.Items.Add(text, descriptionList[text]);
                }
            }

            checkedListBoxIncludeData.ItemCheck += OnItemCheck;
        }

        private void UpdateChart()
        {
            barChart.SeriesCollection.Clear();
            SeriesCollection seriesCollection = new SeriesCollection();
            Dictionary<string, Series> seriesTable = new Dictionary<string, Series>();

            foreach (Data dataItem in dataCollection)
            {
                if (dataItem.Date < dateTimePickerFrom.Value || dataItem.Date > dateTimePickerTo.Value)
                    continue;


                Series series = null;
                string key = String.Empty;

                if (comboBoxCategorize.SelectedIndex == 1)
                {
                    key = dataItem.Category;
                    if (categoryList[key] == false)
                        continue;
                }
                else
                {
                    key = dataItem.Description;
                    if (descriptionList[key] == false)
                        continue;
                }
                
                if (seriesTable.ContainsKey(key))
                    series = seriesTable[key];
                else
                {
                    series = new Series(key);
                    series.Visible = false;
                    seriesTable.Add(key, series);
                    seriesCollection.Add(series);
                }

                float amount = 0;

                switch (comboBoxDisplay.SelectedIndex)
                {
                    case 0: amount = dataItem.AmountSpent;
                        break;
                    case 1: if(dataItem.AmountReimbursed == 0) amount = dataItem.AmountSpent;
                        break;
                    case 2:
                        amount = dataItem.AmountReimbursed;
                        break;
                    default:
                        break;
                }

                if (amount != 0)
                    series.Visible = true;

                Element element = new Element();
                element.XDateTime = dataItem.Date.Date;
                element.YValue = amount;
                series.AddElements(element);
            }

            
            barChart.SeriesCollection.Add(seriesCollection);
            barChart.Title = "Daily Expenditures";

            barChart.XAxis.TimeScaleLabels.Mode = TimeScaleLabelMode.Dynamic;
            barChart.XAxis.TimeInterval = TimeInterval.Days;
            barChart.XAxis.TimeScaleLabels.DayFormatString = "d MMM yy";

            barChart.XAxis.TimeScaleLabels.MonthFormatString = "d MMM yy";
            barChart.XAxis.TimeScaleLabels.MonthTick.Label.Color = Color.DarkBlue;

            barChart.XAxis.TimeScaleLabels.YearFormatString = "d MMM yy";
            barChart.XAxis.TimeScaleLabels.YearTick.Label.Color = Color.DarkGreen;

            barChart.XAxis.Label.Text = "Date";
            barChart.YAxis.Label.Text = "Amount spent";
            barChart.ShadingEffectMode = ShadingEffectMode.Two;

            barChart.LegendBox.Template = "%Icon%Name"; 
            barChart.Invalidate();
        }

        private Dictionary<DateTime, float> GetBarData(Data[] dataCollection)
        {
            Dictionary<DateTime, float> barData = new Dictionary<DateTime, float>();

            foreach (Data dataItem in dataCollection)
            {
                if (dataItem.Category == "Advance")
                    continue;

                if (barData.ContainsKey(dataItem.Date))
                    barData[dataItem.Date] += dataItem.AmountSpent;
                else
                    barData.Add(dataItem.Date, dataItem.AmountSpent);

            }

            return barData;
        }

        #endregion

        private void OnUpdateClick(object sender, EventArgs e)
        {
            UpdateChart();
        }

        private void OnCategoryChanged(object sender, EventArgs e)
        {
            PopulateList();
        }

        private void OnItemCheck(object sender, ItemCheckEventArgs e)
        {
            Dictionary<string, bool> list = comboBoxCategorize.SelectedIndex == 0 ? descriptionList : categoryList;

            list[checkedListBoxIncludeData.Items[e.Index].ToString()] = e.NewValue == CheckState.Checked;           
        }
    }
}
